package operate;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import entry.DBMS;
import entry.OperUtil;
import storage.DisplayField;
import storage.Field;
import storage.Table;

public class ParseCmd {
	private static void parseCondition(String left, String right, ConditionalExpression condition) throws Exception{
		String[] sp = null;
		String table = null;
		String name = null;
		
		condition.setLeft(left);
		condition.setRight(right);
		
		if (left.contains(".") && !left.matches("^\".+\"$")) {
			boolean flag = true;
			sp = left.split("\\.");
			table = sp[0];
			name = sp[1];
			if (!DBMS.loadedTables.containsKey(table)) {
				System.out.println("表不存在" + sp);
				return;
			}
			for (Field field : DBMS.loadedTables.get(table).getAttributes()) {
				if (field.getFieldName().equals(name)) {
					condition.setLeftType(field.getType());
					condition.setLeftcolumn(field.getColumn());
					flag = false;
					break;
				}
			}
			if (flag == false) {
				condition.setLeftConstant(flag);
				condition.setLeftTableName(table);
				condition.setLeftAttribute(name);
			} else {
				throw new RuntimeException("表 " + table + " 中不存在字段 " + name);
			}
			
		}
		if (right.contains(".") && !right.matches("^\".+\"$")) {
			boolean flag = true;
			sp = right.split("\\.");
			table = sp[0];
			name = sp[1];
			if (!DBMS.loadedTables.containsKey(table)) {
				System.out.println("表不存在" + sp);
				return;
			}
			for (Field field : DBMS.loadedTables.get(table).getAttributes()) {
				if (field.getFieldName().equals(name)) {
					condition.setRightType(field.getType());
					condition.setRightcolumn(field.getColumn());
					flag = false;
					break;
				}
			}
			if (flag == false) {
				condition.setRightConstant(flag);
				condition.setRightTableName(table);
				condition.setRightAttribute(name);
			} else {
				throw new RuntimeException("表 " + table + " 中不存在字段 " + name);
			}	
		}
		if (!left.contains(".") && !right.contains(".")) {
			System.out.println("无法识别的比较");
		}
	}

	public static Table parseTable(String account, String name) throws Exception {

		String attr = account.substring(account.indexOf('(') + 1, account.lastIndexOf(')')).trim();

		String[] attrs = attr.split(",");

		if (attrs.length == 0) {
			throw new RuntimeException("无效的字段信息");
		}

		List<Field> fields = new ArrayList<Field>();
		Field field = null;
		String[] infos = null;
		for (int i = 0; i < attrs.length; i++) {// �����ֶ�����
			infos = attrs[i].trim().split("\\s");
			field = new Field();
			field.setColumn(i);
			field.setFieldName(infos[0]);

			if (infos[1].matches("(?i)(Integer)")) {// integer����
				field.setType(infos[1]);
				field.setLength(4);
			} else {// varchar����
				String[] t = infos[1].split("\\(|\\)");
				field.setType(t[0]);
				field.setLength(Integer.parseInt(t[1]));
			}

			if (infos.length == 4) {// �����Դ���������ǿ�
				if (infos[2].equalsIgnoreCase("not")) {// �ǿ�
					field.setNull(false);
				} else {// ����
					field.setPrimary(true);
				}
			}
			fields.add(field);
		}
		File file = new File(DBMS.currentPath + File.separator + name);// �����ļ�
		File configFile = new File(DBMS.currentPath + File.separator + name + ".config");// �����ļ�

		return new Table(name, file, configFile, fields);// ���� �����ļ� �����ļ� �ֶμ���
	}

	
	public static int parseCreate(Create create) {
		String tableP = "(?i)^(create)\\s(table)\\s(\\w+)\\s?\\(\\s?((\\S+\\sInteger)|(\\S+\\sVarchar\\(\\w+\\)))((\\sPrimary\\sKey)|(\\sNot\\sNull))?"
				+ "(\\s?,\\s?((\\S+\\sInteger)|(\\S+\\sVarchar\\(\\w+\\)))((\\sPrimary\\sKey)|(\\sNot\\sNull))?)*\\);$";

		String databaseP = "(?i)^(create)\\s(database)\\s\\S+\\s?;$";
		
		String[] arr = create.getAccount().split("\\s|;|\\(");

		if (create.getAccount().matches(tableP)) {
			create.setName(arr[2]);
			if (DBMS.dataDictionary == null) {
				throw new RuntimeException("未选择数据库");
			}
			if (DBMS.dataDictionary.getTables().contains(create.getName())) {
				throw new RuntimeException("已存在该表");
			} else {
				return 2;
			}
		} else if (create.getAccount().matches(databaseP)) {
			create.setName(arr[2]);
			return 1;
		} else {
			throw new RuntimeException("无效语句");
		}
	}

	public static String parseTableName(String account) {
		return account.split("\\s|;")[2];
	}
	
	public static String subValues(String account) {
		String[] values = account.substring(account.indexOf('(') + 1, account.lastIndexOf(')')).split(",");
		String newLine = "";
		for (String str : values) {
			newLine = newLine + str.trim() + ",";
		}
		return newLine.substring(0, newLine.lastIndexOf(","));
	}
	
	public static String[] subAccount(String account, String start, String end) {
		String temp = null;
		Pattern pattern = null;
		if (start == null) {
			pattern = Pattern.compile("(?i)(?=(add)|(drop)).+(?<=" + end + ")");
		} else {
			pattern = Pattern.compile("(?i)(?=" + start + ").+(?<=" + end + ")");
		}
		Matcher matcher = pattern.matcher(account);
		if (matcher.find()) {
			temp = matcher.group(0);
		}
		temp = temp.split("(?i)(select)|(set)|(add)|(drop)|(from)|(where)|;")[1];
		String[] fields = temp.split("(?i),|(and)");
		for (int i = 0; i < fields.length; i++) {
			fields[i] = fields[i].trim();
		}

		return fields;
	}
	
	public static List<List<String>> subOper(String account, String start, String end) {
		List<List<String>> list= new ArrayList<List<String>>();
		List<String> tlist = null;
		
		Pattern pattern = Pattern.compile("(?i)(?=" + start + ").+(?<=" + end + ")");
		Matcher matcher = pattern.matcher(account);
		String temp = null;
		if (matcher.find()) {
			temp = matcher.group(0);
		}
		temp = temp.split("(?i)(where)|;")[1];
		String[] arr1 = temp.split("(?i)(or)");
		for (String arr2 : arr1) {
			tlist = new ArrayList<String>();
			for (String arr3 : arr2.trim().split("(?i)(and)")) {
				tlist.add(arr3.trim());
			}
			list.add(tlist);
		}
		return list;
	}

	public static void parseSelect(Select select, String account) {
		/*
		 * 暂不支持or条件
		 */
		String pattern = "(?i)^(select)\\s([\\S]+)\\s?(,\\s?[\\S]+)*\\s(from)\\s[\\S]+\\s?(,\\s?[\\S]+)*"
				+ "(\\s(where)\\s[\\S]+[(<)(>)(=)(<=)(>=)][\\S]+(\\s((and)|(or))\\s[\\S]+[(<)(>)(=)(<=)(>=)][\\S]+)*)?;$";
		if (!account.matches(pattern)) {
			System.out.println("语法错误");
			return;
		}
	
		String end = "where";
		if (!account.contains("where") && !account.contains("WHERE")) {
			end = ";";
		}
		String[] fromWhere = subAccount(account, "from", end);
		List<String> list = new ArrayList<String>();
		for (String string : fromWhere) {
			Table table = null;
			try {
				if ((table = DBMS.loadedTables.get(string)) == null) {
					table = OperUtil.loadTable(string);
					DBMS.loadedTables.put(string, table);
				}
			} catch (Exception e) {
				e.printStackTrace();
				return;
			}
			list.add(string);
			select.setNumberTable(select.getNumberTable() + 1);
		}
		select.setTableName(list);
		
		String[] selectFrom = subAccount(account, "select", "from");
		if (selectFrom[0].equals("*")) {
			select.setSeeAll(true);
		} else {
			List<DisplayField> attributes = new ArrayList<DisplayField>();
			DisplayField df = null;
			String tableName = null;
			String fieldName = null;
			for (String fullName : selectFrom) {
				
				try {
					tableName = fullName.split("\\.")[0];
					fieldName = fullName.split("\\.")[1];
				} catch (Exception e) {
					System.out.println(fullName + "��ʽ����ȷ��");
					return;
				}
				if (DBMS.loadedTables.get(tableName) == null) {
					System.out.println("���Ƿ���û��" + tableName + "�����");
					return;
				}
				for (Field field : DBMS.loadedTables.get(tableName).getAttributes()) {//����tableName����ֶμ���
					if (field.getFieldName().equals(fieldName)) {//�ҵ����ֶ�
						df = new DisplayField(field, fullName, tableName);
						break;
					}
				}
				if (df == null) {
					System.out.println("���Ƿ���" + fullName + "�����ڣ�");
					return;
				}
				attributes.add(df);
				select.setNumberFeld(select.getNumberFeld() + 1);
			}
			select.setAttributes(attributes);
		}
		
		if (!account.contains("where") && !account.contains("WHERE")) {
			select.setExistWhereCondition(false);
		} else {
			List<List<String>> arr = subOper(account, "where", ";");
			
			List<List<ConditionalExpression>> lc = new ArrayList<List<ConditionalExpression>>();
			List<ConditionalExpression> conditions = null;
			ConditionalExpression condition = null;
			
			String[] lr = null;
			String left = null;
			String right = null;
			try {
				for (List<String> lor : arr) {
					conditions = new ArrayList<ConditionalExpression>();
					for (String str : lor) {
						condition = new ConditionalExpression();
						if (str.contains("<")) {
							lr = str.split("<");
							left = lr[0];
							right = lr[1];
							condition.setOper("<");
							parseCondition(left, right, condition);
						} else if (str.contains(">")) {
							lr = str.split(">");
							left = lr[0];
							right = lr[1];
							parseCondition(left, right, condition);
							condition.setOper(">");
						} else if (str.contains("<=")) {
							lr = str.split("<=");
							left = lr[0];
							right = lr[1];
							parseCondition(left, right, condition);
							condition.setOper("<=");
						} else if (str.contains(">=")) {
							lr = str.split(">=");
							left = lr[0];
							right = lr[1];
							parseCondition(left, right, condition);
							condition.setOper(">=");
						} else {
							lr = str.split("=");
							left = lr[0];
							right = lr[1];
							parseCondition(left, right, condition);
							condition.setOper("=");
						}
						conditions.add(condition);
					}
					lc.add(conditions);
				}
			} catch (Exception e) {
				System.out.println(e.getMessage());
				e.printStackTrace();
				return;
			}
			select.setConditions(lc);
		}

	}
	
	
}
